/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import comunicacao.AppDatabaseComunicator;
import comunicacao.DBServerConnector;
import comunicacao.GestorZooKeeper;
import comunicacao.GestorZooKeeper2;
import entities.Lugar;
import entities.Teatro;
import java.rmi.RemoteException;
import java.util.ArrayList;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Leonardo Lino Nº45340
 * @author Diogo Pires Nº40351
 */
public class GestorReservas {

    public static final String DATEFORMAT = "yyyy-MM-dd_HH-mm-ss";
    public static final int TIMEOUT = 50; //VALUE IN SECONDS

    Principal prin;
    GestorZooKeeper2 gestorZK;
    DBServerConnector dbConnector;
    private ArrayList<String> listaTeatros = null;

    public GestorReservas(Principal prin, GestorZooKeeper2 gzk) {
        gestorZK = gzk;
        this.prin = prin;
        dbConnector = new DBServerConnector(gestorZK);
    }

    public ArrayList<String> listTheaters() {

        if (listaTeatros == null) {
            listaTeatros = dbConnector.listTheaters();
        }

        return listaTeatros;
    }

    public Teatro getTheater(String theaterName) {

        consola("GET Teatro:" + theaterName);

        Teatro teatro = dbConnector.getTheater(theaterName);
        
        if (teatro==null)
            return null;
        

        teatro = cleanExpired(teatro);

        return teatro;
    }

    private boolean isExpired(Date lugarDate) {

        //cal.set(Calendar.HOUR, (cal.get(Calendar.HOUR) + 6));
        Date current = new Date();
        Calendar calCurrent = Calendar.getInstance();
        calCurrent.setTime(current);

        Calendar calLugar = Calendar.getInstance();
        calLugar.setTime(lugarDate);
        calLugar.set(Calendar.SECOND, (calLugar.get(Calendar.SECOND) + TIMEOUT));

        if (calLugar.before(calCurrent)) {
            return true;
        } else {
            return false;
        }
    }

    public Teatro addReserva(String theaterName, int lugarID, int userID) {

        Teatro teatro = dbConnector.getTheater(theaterName);
        removeOldReserva(teatro, userID);

        Date current = new Date();
        String dateStr = new SimpleDateFormat(DATEFORMAT).format(current);

        String txt = "RESERVA Teatro:" + theaterName + " Lugar:" + Integer.toString(lugarID) + " User:"
                + Integer.toString(userID) + " Date:" + dateStr;
        consola(txt);

        dbConnector.reserveSeat(theaterName, lugarID, userID, dateStr);

        teatro = dbConnector.getTheater(theaterName);
        return teatro;
    }

    public Teatro compraLugar(String theaterName, int lugarID, int userID) {

        Teatro teatro = dbConnector.getTheater(theaterName);
        teatro = cleanExpired(teatro);

        boolean ok = false;

        for (Lugar l : teatro.getLugares()) {

            if (l.getId() == lugarID) {
                if (l.getUserID() == userID && l.getState() == Lugar.STATE_RESERVED) {
                    ok = true;
                }
            }
        }

        if (!ok) {
            return null;
        }

        String txt = "COMPRA Teatro:" + theaterName + " Lugar:" + Integer.toString(lugarID) + " User:"
                + Integer.toString(userID);
        consola(txt);

        if (dbConnector.purchaseSeat(theaterName, lugarID, userID)) {
            //purchse OK
            // Teatro teatro = appDB.getTheater(theaterName);
            return teatro;
        } else {
            //purchase NOT OK
            return null;

        }
    }

    private Teatro cleanExpired(Teatro teatro) {
        try {
            for (Lugar l : teatro.getLugares()) {

                if (l.getTimestamp() != null && !l.getTimestamp().isEmpty()) {
                    Date lugarDate = new SimpleDateFormat(DATEFORMAT).parse(l.getTimestamp());

                    if (isExpired(lugarDate)) {
                        dbConnector.removeSeatReserve(teatro.getNome(), l.getId(), l.getUserID());
                    }

                }
            }

        } catch (ParseException ex) {
            Logger.getLogger(GestorReservas.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }

        teatro = dbConnector.getTheater(teatro.getNome());
        return teatro;
    }

    private Teatro removeOldReserva(Teatro teatro, int userID) {
        for (Lugar l : teatro.getLugares()) {
            if (l.getUserID() == userID) {
                dbConnector.removeSeatReserve(teatro.getNome(), l.getId(), userID);
            }
        }
        return teatro;
    }

    private void consola(String msg) {
        if (Principal.showMsg) {
            prin.consola.append(msg + "\n");
        }
    }

}
